/*
 * @(#)LoginAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.web;

import java.sql.Connection;
import java.sql.Timestamp;
import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.framework.ApplicationContainer;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.AuditLoginOut;
import com.dcivision.framework.dao.AuditLoginOutDAObject;
import com.dcivision.user.auth.AuthenticationHandler;
import com.dcivision.user.auth.PasswordExpiredException;
import com.dcivision.user.bean.UserRecord;

/**
  LoginAction.java

  This class is an action for login.

    @author          Scott Tong
    @company         DCIVision Limited
    @creation date   15/07/2003
    @version         $Revision: 1.60.4.5 $
*/

public class LoginAction extends AbstractAction {

  public static final String REVISION = "$Revision: 1.60.4.5 $";

  protected AuthenticationHandler authHandler = null;
  private String authMethod="FORM";


  /** Creates a new instance of MaintUserGroupAction */
  public LoginAction() {
    super();
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
	//Code Add By joan.xiong			2006/09/04			Bug #6003
	Locale prevLocale = (Locale)request.getSession().getAttribute(org.apache.struts.Globals.LOCALE_KEY);
	//Code Add End
    try {
      this.authHandler = (AuthenticationHandler)Class.forName(SystemParameterFactory.getSystemParameter(SystemParameterConstant.AUTHENICATION_CLASS)).newInstance();
    } catch (Exception e) {
      log.error("Authenication Handler class not found.", e);
      throw new ApplicationException(ErrorConstant.LOGIN_AUTH_CLASS_NOT_FOUND);
    }

    //Code Add By Jim.Zhou			2006/06/08			Bug #3949
    if (!Utility.isEmpty(request.getSession())){
    	request.getSession().invalidate();
    }
    //Code Add End

    LoginForm loginForm = (LoginForm)form;
    //authMethod=Config.getProperty("authMethod");
    //log.debug("method of authentication is :" + (null!=authMethod?authMethod.trim():"FORM"));
    if(null==loginForm ||null==loginForm.getLoginName()||loginForm.getLoginName().trim().length()==0){
      if(null==loginForm){
        loginForm=new LoginForm();
      }
      /*
      if((null!=authMethod&&!authMethod.trim().equals("FORM"))){
        notFormLogin(request,response,loginForm);
      }
      */
    }
    SessionContainer sessionCtn = this.getSessionContainer(request);
    UserRecord userRecord = null;
    Connection conn = null;

    String loginPwd  = loginForm.getLoginPwd();
    String auditStatus = "";
    String userIP = request.getRemoteAddr();

    try {
      // Check whether it is a demo version.
      if (sessionCtn != null && sessionCtn.getAppContainer() != null && sessionCtn.getAppContainer().isDemoVersion() && sessionCtn.getAppContainer().getCurrentLoginUserList().size() >= 2) {
        log.info("This is a demo version of ParaDM. Only 2 concurrent users are allowed.");
        throw new ApplicationException(ErrorConstant.LOGIN_DEMO_TOO_MANY_CONCURRENT_USER);
      }

      // Check whether session is expired.
      if ("expire".equals(loginForm.getAction())) {
        log.debug("Session is expired");
        this.authHandler.Logout(sessionCtn, request);
        throw new ApplicationException(ErrorConstant.LOGIN_SESSION_EXPIRED);
      }

      if (!"login".equals(loginForm.getAction())) {
        if ("redirect".equals(loginForm.getAction())) {
          String userID = request.getParameter("userID");
          //if (sessionCtn == null || Utility.isEmpty(sessionCtn.getUserRecordID()) || (!Utility.isEmpty(userID) && !sessionCtn.getUserRecordID().equals(TextUtility.parseIntegerObj(userID))) ) {
          if (sessionCtn == null || Utility.isEmpty(sessionCtn.getUserRecordID())  ) {
            this.addError(request, "common.message.login_redirect");

            return mapping.findForward("LOGIN");
          } else {

            // Redirect the page to the previous access page.
            if (!Utility.isEmpty(loginForm.getUrl())) {
              try {
                String redirectURL = loginForm.getUrl();
                if (redirectURL.indexOf("isLogin=") < 0) {
                  if (redirectURL.indexOf("?") > 0) {
                    redirectURL += "&isLogin=Y";
                  } else {
                    redirectURL += "?isLogin=Y";
                  }
                }
                response.sendRedirect(redirectURL);
              } catch (Exception ignore) {
                log.error("Cannot redirect url.", ignore);
              }
            } else {
              return mapping.findForward("LOGIN");
            }
          }
        }
        return mapping.findForward("LOGIN");
      }

//      Locale prevLocale = (Locale)request.getSession().getAttribute(org.apache.struts.Globals.LOCALE_KEY);
      if (prevLocale!=null) {
        request.getSession().setAttribute(org.apache.struts.Globals.LOCALE_KEY, prevLocale);
      }
      conn = getConnection(request);

      // Special handling to avoid un-logout session variable remains in the same session.
      SessionContainer tmpSessionCtn = new SessionContainer();
      try{
        userRecord = this.authHandler.Login(loginForm, tmpSessionCtn, request, conn);
      }catch(PasswordExpiredException e){
        if(null!=userRecord){
          request.setAttribute("ID", userRecord.getID());
        }
        return mapping.findForward("CHG_PWD");
      }

      //**************************************************************************************************************
      //Comment out by Ryan Kwan: put the user initialization logic into StandardAuthenticationHandler.initializeLoginUser()
      //**************************************************************************************************************
      /*
      request.getSession().setAttribute(GlobalConstant.SESSION_CONTAINER_KEY, tmpSessionCtn);
      sessionCtn = tmpSessionCtn;

      AuditLoginOut audit = auditLogin(conn, request, userRecord.getID(), userIP, AuditLoginOut.STATUS_LOGIN_SUCCESS, request.getSession().getId(), userRecord.getLoginName());

      sessionCtn.setUserRecord(userRecord);
      sessionCtn.setLoginTime(audit.getLoginDatetime());
      sessionCtn.setUserIPAddress(userIP);
      if (!Utility.isEmpty(userRecord.getLocale())) {
        sessionCtn.setLocale(Utility.getLocaleByString(userRecord.getLocale()));
      } else if (prevLocale!=null) {
        sessionCtn.setLocale(prevLocale);
      }

      if (AuditLoginOut.STATUS_PASSWORD_EXPIRED.equals(sessionCtn.getLoginStatus())) {
        request.setAttribute("ID", userRecord.getID());
        return mapping.findForward("CHG_PWD");
      }
      sessionCtn.setLoginStatus(AuditLoginOut.STATUS_LOGIN_SUCCESS);

      //reset the clipboard items for each login
      if (!Utility.isEmpty(request.getSession().getAttribute("DMS_CLIPBOARD"))){
        List clipBoardList = (List)request.getSession().getAttribute("DMS_CLIPBOARD");
        clipBoardList.removeAll(clipBoardList);
        request.getSession().setAttribute("DMS_CLIPBOARD", clipBoardList);
      }
      //add sessionCtn to PermissionManager sessionctn listener
      PermissionManager.addPermissionListener(sessionCtn);

      //reset the clipboard items for each login
      request.getSession(true).removeAttribute("sessEmailList");
      request.getSession(true).removeAttribute("folder");

      request.getSession(true).removeAttribute("folderTreeParentID");
      request.getSession(true).removeAttribute("publicfolderTreeParentID");
      */

      // Store the client screen resolution in session variable.
      request.getSession().setAttribute(GlobalConstant.CLIENT_SCREEN_WIDTH_KEY, loginForm.getClientScreenWidth());

    } catch (ApplicationException appEx) {
      addError(request, appEx.getActionError());
      String forward = "LOGIN";
      if((ErrorConstant.LOGIN_PASSWORD_EXPIRED).equals(appEx.getMsgCode())) {
        forward = "CHG_PWD";
      }
      return mapping.findForward(forward);
    }

    // Redirect the page to the previous access page.
    if (!Utility.isEmpty(loginForm.getUrl())) {
      try {
        String userID = request.getParameter("userID");
        if (!Utility.isEmpty(userID) && !sessionCtn.getUserRecordID().equals(TextUtility.parseIntegerObj(userID))) {
          //login user is not the target user, redirect to HOME page
          return mapping.findForward("HOME");
        }
        String redirectURL = loginForm.getUrl();
        if (redirectURL.indexOf("?") > 0) {
          redirectURL += "&isLogin=Y";
        } else {
          redirectURL += "?isLogin=Y";
        }
        response.sendRedirect(redirectURL);
      } catch (Exception ignore) {
        log.error("Cannot redirect url.", ignore);
      }
    }
    //Set the session's timeout.
    Integer session_timeout=SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.SESSION_TIMEOUT);
    if(!Utility.isEmpty(session_timeout)&&(session_timeout.intValue()!=0)){
    	if(session_timeout.intValue()>0){
    		request.getSession().setMaxInactiveInterval(session_timeout.intValue()*60);
    	}else{
    		request.getSession().setMaxInactiveInterval(-1);
    	}
    }


    // Return the mapping to Home by default.
    return mapping.findForward("HOME");
  }

  protected AuditLoginOut auditLogin(Connection conn, HttpServletRequest request, Integer userID, String userIP, String status, String sessionID, String loginName) throws ApplicationException {
    AuditLoginOutDAObject auditLoginOutDAObject = new AuditLoginOutDAObject(null, conn);
    AuditLoginOut auditLoginOut = new AuditLoginOut();
    auditLoginOut.setLoginName(loginName);
    auditLoginOut.setUserRecordID(userID);
    auditLoginOut.setIPAddress(userIP);
    auditLoginOut.setSessionID(sessionID);
    auditLoginOut.setLoginDatetime(new Timestamp(System.currentTimeMillis()));
    auditLoginOut.setLoginStatus(status);

    if (!isError(request)){
    	((ApplicationContainer)request.getSession().getServletContext().getAttribute(GlobalConstant.APPLICATION_CONTAINER_KEY)).loginUser(auditLoginOut);
    }

    auditLoginOut = (AuditLoginOut)auditLoginOutDAObject.insertObject(auditLoginOut);
    try {
      conn.commit();
    } catch (Exception e) {
      throw new ApplicationException(ErrorConstant.DB_COMMIT_ERROR);
    }
    return auditLoginOut;
  }

  public String getMajorDAOClassName() {
    return(null);
  }

  public String getFunctionCode() {
    return(null);
  }
/*
  private void notFormLogin(HttpServletRequest req, HttpServletResponse resp,LoginForm form){
  	UserRecord authUser=(UserRecord)req.getAttribute("AuthUserRecord");
  	if(null!=authUser){
		form.setLoginName(authUser.getLoginName());
  		form.setLoginPwd(authUser.getLoginPwd());
  		form.setAction("login");
  		form.setClientScreenWidth("1024");
  		if (req.getParameter(GlobalConstant.LANGUAGE_PARAMETER) != null) {
  		   (req.getSession()).setAttribute(org.apache.struts.Globals.LOCALE_KEY, Utility.getLocaleByString(req.getParameter(GlobalConstant.LANGUAGE_PARAMETER)));
  		}
  	}
  }
*/
}